﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LogManager.Utils.Diagnostics
{
    /// <summary>
    /// Raises an event each time a WPF Binding error occurs.
    /// </summary>
    public sealed class BindingErrorListener : IDisposable
    {
        private readonly StringBuilder _errors = new StringBuilder();
        public string Errors { get { return _errors.ToString(); } }

        private readonly ObservableTraceListener _traceListener;
        private readonly SourceLevels _previousSwitchLevel;

        static BindingErrorListener()
        {
            PresentationTraceSources.Refresh();
        }

        public BindingErrorListener()
        {
            _traceListener = new ObservableTraceListener();
            _traceListener.TraceCatched += traceListener_TraceCatched;

            _previousSwitchLevel = PresentationTraceSources.DataBindingSource.Switch.Level;
            PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Error;
            PresentationTraceSources.DataBindingSource.Listeners.Add(_traceListener);
        }

        private void traceListener_TraceCatched(string error)
        {
            _errors.AppendLine(error);
        }

        public void Dispose()
        {
            _traceListener.TraceCatched -= traceListener_TraceCatched;
            PresentationTraceSources.DataBindingSource.Listeners.Remove(_traceListener);
            PresentationTraceSources.DataBindingSource.Switch.Level = _previousSwitchLevel;
            _traceListener.Dispose();
            _errors.Clear();
        }

        /// <summary>
        /// Event raised each time a WPF binding error occurs
        /// </summary>
        public event Action<string> ErrorCatched
        {
            add { _traceListener.TraceCatched += value; }
            remove { _traceListener.TraceCatched -= value; }
        }
    }
}
